#include "Car.h"
#include <iomanip>
#include <cerrno>
#include <iostream>
#include <fstream>   // 关键：补充 ofstream/ifstream 头文件
#include <sstream>   // 关键：补充 ostringstream/istringstream 头文件
#include <vector>    // 补充：vector 类的声明（若编译器未自动包含）

void Car::initDefaultComponents(){

    //初始化底盘
    chassis.id="dp"+carId.substr(5,13);//底盘编号
    chassis.model="SCOUT MINI";
    chassis.wheelbase="451mm";
    chassis.trackWidth="490mm";
    chassis.minGroundClear="115mm";
    chassis.minTurnRadius="0mm";
    chassis.driveType="四驱四轮";
    chassis.maxRange="10km";
    for(int i=0;i<4;i++){
        chassis.tires[i].type="公路轮、麦克纳姆轮";
        chassis.tires[i].size="175mm";
    }

    //初始化AGX套件
    agxKit.model="AGX Xavier";
    agxKit.aiPerformance="32 TOPS";
    agxKit.cudaCores="512";
    agxKit.tensorCores="64";
    agxKit.vram="32G";
    agxKit.storage="32G";

    //初始化双目摄像头
    stereoCamera.model="RealSense D4351";
    stereoCamera.camModule="D430";
    stereoCamera.rgbRes="1920x1080";
    stereoCamera.rgbFps="30";
    stereoCamera.fov="87*58";
    stereoCamera.depthFps="90";

    //初始多线激光雷达
    lidar.model="RS-Helios-16p";
    lidar.lines="16";
    lidar.testRange="100m";
    lidar.power="8W";

    //初始陀螺仪
    gyroscope.model="CH110";
    gyroscope.manufacturer="NXP";
    
    //初始化液晶显示屏
    lcdScreen.size="11.6";
    lcdScreen.model="super";

    //初始化电池
    bettery.params="24V/15Ah";
    bettery.outputVolt="24V";
    bettery.chargeTime="2H";

    
};

Car::Car(){
    carId="dp00000000";//默认编号
    initDefaultComponents();//初始化默认小车
}

Car::Car(const std::string& carId){
    this->carId=carId;
    initDefaultComponents();//初始化默认小车
}

void Car::setCarId(const std::string& carId){
    //校验
    if(carId.substr(0,5)=="cqusn" && carId.length()==16){
        this->carId=carId;
        this->chassis.id="dp"+carId.substr(5,13);//更新底盘编号
        std::cout<<"小车编号设置成功"<<std::endl;
    }else{
        std::cerr<<"小车编号格式错误（需cqusn打头16位）"<<std::endl;
    }
}

void Car::assignStudent(const Student& student){
    this->student=student;
    std::cout<<"学生分配成功"<<std::endl;
}

void Car::setChassis(const Chassis& chassis){
    this->chassis=chassis;
    std::cout<<"底盘信息设置成功"<<std::endl;
}

void Car::setAGXKit(const AGXKit& agxKit){
    this->agxKit=agxKit;
    std::cout<<"AGX套件信息设置成功"<<std::endl;
}

void Car::setStereoCamera(const StereoCamera& stereoCamera){
    this->stereoCamera=stereoCamera;
    std::cout<<"双目摄像头信息设置成功"<<std::endl;
}

void Car::setLiDAR(const LiDAR& lidar){
    this->lidar=lidar;
    std::cout<<"多线激光雷达信息设置成功"<<std::endl;
}

void Car::setGyroscope(const Gyroscope& gyroscope){
    this->gyroscope=gyroscope;
    std::cout<<"9轴陀螺仪信息设置成功"<<std::endl;
}

void Car::setLCDScreen(const LCDScreen& lcdScreen){
    this->lcdScreen=lcdScreen;
    std::cout<<"液晶显示屏信息设置成功"<<std::endl;
}

void Car::setBattery(const Bettery& bettery){
    this->bettery=bettery;
    std::cout<<"电池信息设置成功"<<std::endl;
}

Student Car::getStudent(){
    return student;
}

std::string Car::getCarId(){
    return carId;
}

Chassis Car::getChassis(){
    return chassis;
}

AGXKit Car::getAGXKit(){
    return agxKit;
}

StereoCamera Car::getStereoCamera(){
    return stereoCamera;
}

LiDAR Car::getLiDAR(){
    return lidar;
}

Gyroscope Car::getGyroscope(){
    return gyroscope;
}

LCDScreen Car::getLCDScreen(){
    return lcdScreen;
}

Bettery Car::getBettery(){
    return bettery;
}

bool Car::getIsAssignedStudent() const {
    return isAssignedStudent;
}
// 展示Car信息函数
void Car::displayCarInfo(){
    std::cout<<"-----------------小车信息-----------------"<<std::endl;
    std::cout<<"小车编号："<<carId<<std::endl;
    if(!isAssignedStudent){
        std::cout<<"分配学生："<<student.name<<"("<<student.id<<")"<<std::endl;
    }else{
        std::cout<<"分配学生：未分配"<<std::endl;
    }
    std::cout<<"-----------------底盘信息-----------------"<<std::endl;
    std::cout<<"底盘编号："<<chassis.id<<std::endl;
    std::cout<<"型号："<<chassis.model<<std::endl;
    std::cout<<"轴距："<<chassis.wheelbase<<std::endl;
    std::cout<<"轮距："<<chassis.trackWidth<<std::endl;
    std::cout<<"最小离地间隙："<<chassis.minGroundClear<<std::endl;
    std::cout<<"最小转弯半径："<<chassis.minTurnRadius<<std::endl;
    std::cout<<"驱动类型："<<chassis.driveType<<std::endl;
    std::cout<<"最大行程："<<chassis.maxRange<<std::endl;
    for(int i=0;i<4;i++){
        std::cout<<"轮胎"<<i+1<<"："<<chassis.tires[i].type<<","<<chassis.tires[i].size<<std::endl;
    }

    std::cout<<"-----------------AGX套件信息-----------------"<<std::endl;
    std::cout<<"型号："<<agxKit.model<<std::endl;
    std::cout<<"AI性能："<<agxKit.aiPerformance<<std::endl;
    std::cout<<"CUDA核心数："<<agxKit.cudaCores<<std::endl;
    std::cout<<"Tensor核心数："<<agxKit.tensorCores<<std::endl;
    std::cout<<"显存："<<agxKit.vram<<std::endl;
    std::cout<<"储存："<<agxKit.storage<<std::endl;

    std::cout<<"-----------------双目摄像头信息-----------------"<<std::endl;
    std::cout<<"型号："<<stereoCamera.model<<std::endl;
    std::cout<<"摄像头模块："<<stereoCamera.camModule<<std::endl; // 补全std::endl
    std::cout<<"RGB分辨率："<<stereoCamera.rgbRes<<std::endl; // 补充缺失的摄像头信息输出
    std::cout<<"RGB帧率："<<stereoCamera.rgbFps<<std::endl;
    std::cout<<"FOV视场角："<<stereoCamera.fov<<std::endl;
    std::cout<<"深度帧率："<<stereoCamera.depthFps<<std::endl;

    std::cout<<"-----------------多线激光雷达信息-----------------"<<std::endl;
    std::cout<<"型号："<<lidar.model<<std::endl;
    std::cout<<"通道数："<<lidar.lines<<std::endl;
    std::cout<<"测试范围："<<lidar.testRange<<std::endl;
    std::cout<<"功耗："<<lidar.power<<std::endl;

    std::cout<<"-----------------9轴陀螺仪信息-----------------"<<std::endl;
    std::cout<<"型号："<<gyroscope.model<<std::endl;
    std::cout<<"厂家："<<gyroscope.manufacturer<<std::endl;

    std::cout<<"-----------------液晶显示屏信息-----------------"<<std::endl;
    std::cout<<"尺寸："<<lcdScreen.size<<"英寸"<<std::endl; // 补充单位，更清晰
    std::cout<<"型号："<<lcdScreen.model<<std::endl;

    std::cout<<"-----------------电池信息-----------------"<<std::endl;
    std::cout<<"参数："<<bettery.params<<std::endl;
    std::cout<<"对外供电："<<bettery.outputVolt<<std::endl;
    std::cout<<"充电时间："<<bettery.chargeTime<<std::endl;
}

// // 序列化对象到输出流
// void Car::serialize(std::ostream& os) const {
//         os << chassis<< "\n";
//         os << agxKit << "\n";
//         os << stereoCamera << "\n";
//         os << lidar << "\n";
//         os << gyroscope << "\n";
//         os << lcdScreen << "\n";
//         os << bettery << "\n";
//         os << student << "\n";
//         os << carId << "\n";
//         os << isAssignedStudent << "\n";
// }

std::ostream& operator<<(std::ostream& os, const Tire& tire) {
    // 用特殊分隔符 "|" 分隔字段，避免与内容冲突
    os << tire.type << "|" << tire.size;
    return os;
}
std::istream& operator>>(std::istream& is, Tire& tire) {
    // 按 "|" 分割读取字段
    std::getline(is, tire.type, '|');
    std::getline(is, tire.size, '|');
    return is;
}

std::ostream& operator<<(std::ostream& os, const Chassis& chassis) {
    os << chassis.id << "|" 
       << chassis.model << "|" 
       << chassis.wheelbase << "|" 
       << chassis.trackWidth << "|" 
       << chassis.minGroundClear << "|" 
       << chassis.minTurnRadius << "|" 
       << chassis.driveType << "|" 
       << chassis.maxRange;
    // 写入4个轮胎
    for (int i = 0; i < 4; ++i) {
        os << "|" << chassis.tires[i]; // 复用Tire的<<重载
    }
    return os;
}
std::istream& operator>>(std::istream& is, Chassis& chassis) {
    std::getline(is, chassis.id, '|');
    std::getline(is, chassis.model, '|');
    std::getline(is, chassis.wheelbase, '|');
    std::getline(is, chassis.trackWidth, '|');
    std::getline(is, chassis.minGroundClear, '|');
    std::getline(is, chassis.minTurnRadius, '|');
    std::getline(is, chassis.driveType, '|');
    std::getline(is, chassis.maxRange, '|');
    // 读取4个轮胎
    for (int i = 0; i < 4; ++i) {
        is >> chassis.tires[i]; // 复用Tire的>>重载
        if (i < 3) is.ignore(1); // 忽略轮胎间的"|"分隔符
    }
    return is;
}

std::ostream& operator<<(std::ostream& os, const AGXKit& agxKit) {
    os << agxKit.model << "|" 
       << agxKit.aiPerformance << "|" 
       << agxKit.cudaCores << "|" 
       << agxKit.tensorCores << "|" 
       << agxKit.vram << "|" 
       << agxKit.storage;
    return os;
}
std::istream& operator>>(std::istream& is, AGXKit& agxKit) {
    std::getline(is, agxKit.model, '|');
    std::getline(is, agxKit.aiPerformance, '|');
    std::getline(is, agxKit.cudaCores, '|');
    std::getline(is, agxKit.tensorCores, '|');
    std::getline(is, agxKit.vram, '|');
    std::getline(is, agxKit.storage, '|');
    return is;
}

std::ostream& operator<<(std::ostream& os, const StereoCamera& stereoCam) {
    os << stereoCam.model << "|" 
       << stereoCam.camModule << "|" 
       << stereoCam.rgbRes << "|" 
       << stereoCam.rgbFps << "|" 
       << stereoCam.fov << "|" 
       << stereoCam.depthFps;
    return os;
}
std::istream& operator>>(std::istream& is, StereoCamera& stereoCam) {
    std::getline(is, stereoCam.model, '|');
    std::getline(is, stereoCam.camModule, '|');
    std::getline(is, stereoCam.rgbRes, '|');
    std::getline(is, stereoCam.rgbFps, '|');
    std::getline(is, stereoCam.fov, '|');
    std::getline(is, stereoCam.depthFps, '|');
    return is;
}

// --------------------------
// 5. 实现 LiDAR 运算符重载
// --------------------------
std::ostream& operator<<(std::ostream& os, const LiDAR& lidar) {
    os << lidar.model << "|" 
       << lidar.lines << "|" 
       << lidar.testRange << "|" 
       << lidar.power;
    return os;
}
std::istream& operator>>(std::istream& is, LiDAR& lidar) {
    std::getline(is, lidar.model, '|');
    std::getline(is, lidar.lines, '|');
    std::getline(is, lidar.testRange, '|');
    std::getline(is, lidar.power, '|');
    return is;
}

// --------------------------
// 6. 实现 Gyroscope 运算符重载
// --------------------------
std::ostream& operator<<(std::ostream& os, const Gyroscope& gyro) {
    os << gyro.model << "|" << gyro.manufacturer;
    return os;
}
std::istream& operator>>(std::istream& is, Gyroscope& gyro) {
    std::getline(is, gyro.model, '|');
    std::getline(is, gyro.manufacturer, '|');
    return is;
}

// --------------------------
// 7. 实现 LCDScreen 运算符重载
// --------------------------
std::ostream& operator<<(std::ostream& os, const LCDScreen& lcd) {
    os << lcd.size << "|" << lcd.model;
    return os;
}
std::istream& operator>>(std::istream& is, LCDScreen& lcd) {
    std::getline(is, lcd.size, '|');
    std::getline(is, lcd.model, '|');
    return is;
}

// --------------------------
// 8. 实现 Bettery 运算符重载
// --------------------------
std::ostream& operator<<(std::ostream& os, const Bettery& battery) {
    os << battery.params << "|" 
       << battery.outputVolt << "|" 
       << battery.chargeTime;
    return os;
}
std::istream& operator>>(std::istream& is, Bettery& battery) {
    std::getline(is, battery.params, '|');
    std::getline(is, battery.outputVolt, '|');
    std::getline(is, battery.chargeTime, '|');
    return is;
}

// --------------------------
// 9. 实现 Student 运算符重载
// --------------------------
std::ostream& operator<<(std::ostream& os, const Student& student) {
    os << student.id << "|" << student.name;
    return os;
}
std::istream& operator>>(std::istream& is, Student& student) {
    std::getline(is, student.id, '|');
    std::getline(is, student.name, '|');
    return is;
}


// 序列化小车信息到输出流
void Car::serialize(std::ostream& os) const {
    // 使用特殊标记分隔每个主要组件，方便反序列化
    os << chassis << "\n";
    os << agxKit << "\n";
    os << stereoCamera << "\n";
    os << lidar << "\n";
    os << gyroscope << "\n";
    os << lcdScreen << "\n";
    os << bettery << "\n";
    os << student << "\n";
    os << carId << "\n";
    os << isAssignedStudent << "\n";
}

// 从输入流反序列化小车信息
void Car::deserialize(std::istream& is) {
    std::string line;
    
    // 读取底盘信息
    std::getline(is, line);
    std::istringstream(line) >> chassis;
    
    // 读取AGX套件信息
    std::getline(is, line);
    std::istringstream(line) >> agxKit;
    
    // 读取双目摄像头信息
    std::getline(is, line);
    std::istringstream(line) >> stereoCamera;
    
    // 读取激光雷达信息
    std::getline(is, line);
    std::istringstream(line) >> lidar;
    
    // 读取陀螺仪信息
    std::getline(is, line);
    std::istringstream(line) >> gyroscope;
    
    // 读取显示屏信息
    std::getline(is, line);
    std::istringstream(line) >> lcdScreen;
    
    // 读取电池信息
    std::getline(is, line);
    std::istringstream(line) >> bettery;
    
    // 读取学生信息
    std::getline(is, line);
    std::istringstream(line) >> student;
    
    // 读取小车编号
    std::getline(is, carId);
    
    // 读取学生分配状态
    std::getline(is, line);
    isAssignedStudent = (line == "1");
}

// 保存vector<Car>到文件
bool Car::saveCarsToFile(const std::vector<Car>& cars, const std::string& filename) {
    std::ofstream file(filename, std::ios::out | std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "无法打开文件进行写入: " << filename << std::endl;
        return false;
    }
    
    // 先写入小车数量
    size_t count = cars.size();
    file.write(reinterpret_cast<const char*>(&count), sizeof(count));
    
    // 逐个写入小车信息
    for (const auto& car : cars) {
        // 先写入该小车序列化后的字符串长度，再写入内容
        std::ostringstream oss;
        car.serialize(oss);
        std::string data = oss.str();
        size_t length = data.size();
        
        file.write(reinterpret_cast<const char*>(&length), sizeof(length));
        file.write(data.c_str(), length);
    }
    
    file.close();
    return true;
}

// 从文件加载vector<Car>
bool Car::loadCarsFromFile(std::vector<Car>& cars, const std::string& filename) {
    std::ifstream file(filename, std::ios::in | std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "无法打开文件进行读取: " << filename << std::endl;
        return false;
    }
    
    cars.clear(); // 清空原有数据
    
    // 先读取小车数量
    size_t count;
    file.read(reinterpret_cast<char*>(&count), sizeof(count));
    
    // 逐个读取小车信息
    for (size_t i = 0; i < count; ++i) {
        // 先读取序列化字符串的长度，再读取内容
        size_t length;
        file.read(reinterpret_cast<char*>(&length), sizeof(length));
        
        std::string data(length, '\0');
        file.read(&data[0], length);
        
        // 反序列化到Car对象
        Car car;
        std::istringstream iss(data);
        car.deserialize(iss);
        
        cars.push_back(car);
    }
    
    file.close();
    return true;
}












